package com.search.service;

import com.alibaba.fastjson2.JSONObject;
import com.search.entity.BorrowBook;
import com.search.entity.DoubanBook;
import com.search.examples.*;
import lombok.extern.slf4j.Slf4j;
import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.nodes.Node;
import org.jsoup.select.Elements;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;

import java.awt.*;
import java.util.Date;
import java.util.List;

@Slf4j
@Service
@Repository
public abstract class DoubanBookAllLibsService {

    protected ThreadLocal<Integer> currentPageBookSum = ThreadLocal.withInitial(()->0);

    protected ThreadLocal<Boolean> isEmpty = ThreadLocal.withInitial(()->false);

    protected ThreadLocal<Integer> counter = ThreadLocal.withInitial(()->0);

    protected ThreadLocal<Integer> bookSum = ThreadLocal.withInitial(()->0);

    float ratingLine = 0.0f;

    int getDataType = 0;//0是库里没有，全线上查。1是库里走，不查线上。2是库里有部分数据，先从库里查，没有再查线上

    @Autowired
    protected BorrowBookService borrowBookService;

    @Autowired
    protected DoubanBookService doubanBookService;


    public abstract String getListIdfromUrl(String url);

    public abstract String dealUrl(String url,int bookSum);

    public abstract Integer bookSumIncrease(Integer bookSum);

    public abstract List<JSONObject> dealPageData(Document doc);

    Document getDoc(String url,int reTry) throws Exception {

        try{
            Connection connection = Jsoup.connect(url);
            connection.header("sec-fetch-site","none");
            connection.header("upgrade-insecure-requests","1");
            connection.header("cookie","ll=\"108288\"; bid=F9-W7MCOcmY; _pk_id.100001.3ac3=79660cc1e01fac24.1723820565.; douban-fav-remind=1; __utmv=30149280.6649; __yadk_uid=ZHJhWDSJiNZ2MH9YhVnmgxQbFvfyMqfI; _vwo_uuid_v2=D73A86D855AEA200504494DB07D45E995|117418fc07de55be6e666a1331b7531e; _vwo_uuid_v2=D73A86D855AEA200504494DB07D45E995|117418fc07de55be6e666a1331b7531e; _ga_RXNMP372GL=GS1.1.1725441315.5.1.1725442928.60.0.0; _ga=GA1.2.372323296.1723824931; _ga_PRH9EWN86K=GS1.2.1726111153.1.0.1726111153.0.0.0; __utmz=30149280.1726363540.81.24.utmcsr=google|utmccn=(organic)|utmcmd=organic|utmctr=(not%20provided); __utmz=81379588.1727533803.59.48.utmcsr=douban.com|utmccn=(referral)|utmcmd=referral|utmcct=/link2/; viewed=\"36609039_31313391_30908519_30783821_30582710_30540166_30726005_30779961_30819205_30521794\"; push_noty_num=0; push_doumail_num=0; dbcl2=\"66490248:EtA/OK6JkwE\"; ct=y; ck=_9nv; frodotk_db=\"d0fd3ce1e82c0f5d72f7b6a5b8842e17\"; _pk_ref.100001.3ac3=%5B%22%22%2C%22%22%2C1735633283%2C%22https%3A%2F%2Fwww.douban.com%2F%22%5D; _pk_ses.100001.3ac3=1; ap_v=0,6.0; __utma=30149280.43806817.1723824835.1734008858.1735638240.94; __utmc=30149280; __utmt_douban=1; __utmb=30149280.1.10.1735638240; __utma=81379588.1255629465.1723824837.1727533803.1735638240.60; __utmc=81379588; __utmt=1; __utmb=81379588.1.10.1735638240");
            connection.header("sec-ch-ua","\"Google Chrome\";v=\"131\", \"Chromium\";v=\"131\", \"Not_A Brand\";v=\"24\"");
            connection.header("accept","text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7");
            connection.header("sec-ch-ua-platform","Windows");
            connection.header("sec-fetch-user","?1");
            connection.header("cache-control","max-age=0");
            connection.header("sec-fetch-mode","navigate");
            connection.header("accept-language","zh-CN,zh;q=0.9");
            connection.header("user-agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36");
            connection.header("sec-fetch-dest","document");
            connection.header("priority","u=0, i");
            connection.header("sec-ch-ua-mobile","?0");
            Document doc = connection.get();
            log.info("请求成功"+url);
            return doc;
        }catch (Exception e){
            log.error("jsoup报错,重试"+url,e.toString());
            Thread.sleep(3000);
            if(reTry>0){
                return getDoc(url,reTry-1);
            }else{
                throw e;
            }

        }
    }

    public DoubanBook getBookDetail(String detailUrl,String tag) throws Exception {

        Document detail = getDoc(detailUrl,10);
        int evaluateNum = 0;
        float rating = 0.0f;
        int beginIndex = detailUrl.substring(0,detailUrl.length()-1).lastIndexOf("/");
        String id = detailUrl.substring(beginIndex+1,detailUrl.length()-1);

        String name = detail.select("span[property='v:itemreviewed']").get(0).text().trim();
        Elements votes = detail.select("span[property='v:votes']");
        Elements averages = detail.select("strong[property='v:average']");
        log.info("线上查询图书详情"+detail.title());
        if(averages.size()>0){
            rating = Float.parseFloat(averages.get(0).text().trim());
        }

        if(votes.size()>0){
            evaluateNum = Integer.parseInt(votes.get(0).text().trim());
        }
        //Elements infos = detail.select("div#info");
        Element info = detail.getElementById("info");
        int isbnIndex=0;
        int subTitleIndex = 0;
        for(Node node:info.childNodes()){
            String text = node.toString();
            if(text.contains("ISBN")){
                //System.out.println(text);
                //System.out.println(node.siblingIndex());
                isbnIndex = node.siblingIndex();
            }
            if(text.contains("副标题")){
                subTitleIndex = node.siblingIndex();
                if(subTitleIndex>0){
                    String subTitle = info.childNodes().get(subTitleIndex+1).toString();
                    name += subTitle;
                }
            }

        }
        //System.out.println(info.childNodes().get(index+1).toString());
        String isbn = info.childNodes().get(isbnIndex+1).toString().trim();
        //存入豆瓣图书数据
        DoubanBook doubanBook = new DoubanBook();
        doubanBook.setBookName(name);
        doubanBook.setUrl(detailUrl);
        doubanBook.setRating(rating);
        doubanBook.setEvaluateNum(evaluateNum);
        doubanBook.setIsbn(isbn);
        doubanBook.setTag(tag);
        doubanBook.setInsertTime(new Date());
        /*if(detailUrl.contains("tag")){
            int tagIndex = detailUrl.indexOf("tag");
            int queIndex = detailUrl.indexOf("?");
            doubanBook.setTag(detailUrl.substring(tagIndex+4,queIndex-1));

        }*/
        doubanBook.setId(id);
        try{
            doubanBookService.saveNotNull(doubanBook);
        }catch (Exception e){
            log.error("豆瓣book插入出错"+name);
            throw e;
        }
        //log.info("豆瓣book插入"+isbn);
        return doubanBook;
    }

    public JSONObject queryBooks(String url, String source, String classify){

        JSONObject result = new JSONObject();
        /*int threadNum = 10;
        while (threadNum>0){
            new Thread(new QueryDouBanPageThread(20*5*(10-threadNum),50/threadNum,source,classify,url)).start();
            threadNum--;
        }*/

        Document doc=null;
        List<JSONObject> urls = null;

        int startIndex = 0;
        url = url+"?start="+startIndex+"&type=S";

        do{
            try{
                int currentPageBookSum = 0;
                try{
                    url = url.replaceAll("\\d+",""+startIndex);
                    log.info("begin"+startIndex);
                    doc = getDoc(url,20);
                }catch (Exception e){
                    log.error("请求豆瓣分页出错"+e.toString());
                    continue;
                }
                //log.debug("处理到第"+bookSum+"本书");

                urls = dealPageData(doc);
                log.info("请求"+url+"返回"+urls.size());
                if(urls.size()==0){
                    log.info(Thread.currentThread().getName()+"最后一次请求"+url);
                }else{
                    log.info("第一本书"+urls.get(0).get("detailUrl"));
                }
                for(JSONObject ele:urls){
                    String detailUrl = (String)ele.get("detailUrl");
                    float rating = Float.parseFloat(ele.get("rating").toString());
                    String name =null;
                    int evaluateNum = 0;
                    DoubanBook resultBook = null;
                    int counterVal = counter.get();
                    counterVal++;
                    counter.set(counterVal);
                    log.info(Thread.currentThread().getName()+"处理第"+counterVal+"本书");
                    if(rating>ratingLine){
                        Document detail = null;
                        try{
                            int beginIndex = detailUrl.substring(0,detailUrl.length()-1).lastIndexOf("/");
                            String id  = detailUrl.substring(beginIndex+1,detailUrl.length()-1);
                            String tag = null;
                            if(url.contains("tag")){
                                int tagIndex = url.indexOf("tag");
                                int queIndex = url.indexOf("?");
                                tag = url.substring(tagIndex+4,queIndex).trim();
                            }

                            if(1==getDataType){
                                resultBook = doubanBookService.findOne(id);
                            }else if(0==getDataType) {
                                resultBook = getBookDetail(detailUrl,tag);
                            }else if(2==getDataType){
                                resultBook = doubanBookService.findOne(id);
                                    /*if(!"企业史".equals(resultBook.getTag())){
                                        other++;
                                    }*/
                                //log.info("other"+other);
                                //log.info("exist"+exist);

                                if(null==resultBook){
                                    log.info("库里没有"+id+"---------------------------------------------------------------------------------------------------------------------");
                                    resultBook = getBookDetail(detailUrl,tag);
                                    //Toolkit.getDefaultToolkit().beep();
                                }else{
                                    //exist++;
                                    //log.info("名称"+resultBook.getBookName());
                                }
                            }
                        }catch (DuplicateKeyException e){
                            log.error("书籍已经存在，跳过");
                            //exist++;
                            continue;
                        }catch (Exception e2){
                            log.error("获取书籍详情出错",e2.getCause());
                                /*StackTraceElement[] eles =e2.getStackTrace();
                                if(null!=eles && eles.length>0){
                                    log.error(eles[0].getLineNumber()+"行出错");
                                }*/

                            continue;
                        }

                        //System.out.println(name+"------"+url+"------"+isbn);
                        CapitalSearch capitalSearch = new CapitalSearch();

                        if(null==borrowBookService.findOne(resultBook.getIsbn().trim()) ){

                            saveBook("capital",resultBook, CapitalSearch.search(resultBook.getIsbn().trim()));
                            saveBook("haiDian",resultBook, HaiDianSearch.search(resultBook.getIsbn().trim()));
                            saveBook("chaotu",resultBook,ChaoTuSearch.search(resultBook.getIsbn().trim(),resultBook.getBookName().trim()));
                            saveBook("daXing",resultBook, DaxingSearch.search(resultBook.getIsbn().trim()));
                            saveBook("fangShan",resultBook, FangShanSearch.search(resultBook.getIsbn().trim()));
                            saveBook("miYun",resultBook, MiYunSearch.search(resultBook.getIsbn().trim()));
                            saveBook("pingGu",resultBook, PingGuSearch.search(resultBook.getIsbn().trim()));
                            saveBook("shiJingShan",resultBook, ShiJingShanSearch.search(resultBook.getIsbn().trim()));
                            saveBook("tongZhou",resultBook, TongZhouSearch.search(resultBook.getIsbn().trim()));
                            saveBook("yanQing",resultBook, YanQingSearch.search(resultBook.getIsbn().trim()));
                        }

                    }

                }
            }catch(Exception e){
                log.error("出错了"+e.getMessage());
                log.error("StackTrace"+e.getStackTrace());
                log.error("local",e.getLocalizedMessage());
                log.error("cause",e.getCause());
                log.error("press"+e.getSuppressed());
                log.error("class"+e.getClass());
            }
            //翻页
            bookSum.set(bookSumIncrease(bookSum.get()));
            startIndex+=20;
            log.info("bookSum"+bookSum.get());
        }while (!isEmpty.get());
        log.info("结束了"+startIndex);
        Toolkit.getDefaultToolkit().beep();

        return result;
    }

    private void saveBook(String library,DoubanBook resultBook,int holding){
        BorrowBook book = new BorrowBook();
        book.setBookName(resultBook.getBookName().trim());
        book.setDetailUrl(resultBook.getUrl());
        book.setIsbn(resultBook.getIsbn());
        book.setRating(resultBook.getRating());
        book.setListId("");
        book.setClassify(resultBook.getTag());
        book.setLibrary(library);
        book.setSource("doubanList");
        book.setListName("");
        book.setInsertTime(new Date());
        book.setIsCollect(0);
        book.setEvaluateNum(resultBook.getEvaluateNum());
        book.setHolding(holding);
        try{
            borrowBookService.saveNotNull(book);
            //sum++;
        }catch (DuplicateKeyException duplicateKeyException ){
            borrowBookService.updateNotNullById(book);
        }catch (Exception e){
            log.error("borrowBook插入出错"+e.getMessage()+book.toString());
        }
    }


    class QueryDouBanPageThread implements Runnable{

        int startIndex;
        int pageNum;

        String source;

        String classify;

        String url;

        QueryDouBanPageThread(int startIndex,int pageNum, String source,String classify,String url){
            this.startIndex = startIndex;
            this.pageNum = pageNum;
            this.classify = classify;
            this.source = source;
            this.url = url;
        }

        @Override
        public void run() {

            Document doc=null;
            JSONObject result = new JSONObject();
            List<JSONObject> urls = null;

            url = url+"/?start="+startIndex+"&type=S";

            do{
                try{
                    int currentPageBookSum = 0;
                    try{
                        url = url.replaceAll("\\d+",""+startIndex);
                        doc = getDoc(url,20);
                    }catch (Exception e){
                        log.error("请求豆瓣分页出错"+e.toString());
                        continue;
                    }
                    //log.debug("处理到第"+bookSum+"本书");

                    urls = dealPageData(doc);
                    log.info("请求"+url+"返回"+urls.size());
                    if(urls.size()==0){
                        log.info(Thread.currentThread().getName()+"最后一次请求"+url);
                    }else{
                        log.info("第一本书"+urls.get(0).get("detailUrl"));
                    }
                    for(JSONObject ele:urls){
                        String detailUrl = (String)ele.get("detailUrl");
                        float rating = Float.parseFloat(ele.get("rating").toString());
                        String name =null;
                        int evaluateNum = 0;
                        DoubanBook resultBook = null;
                        int counterVal = counter.get();
                        counterVal++;
                        counter.set(counterVal);
                        log.info(Thread.currentThread().getName()+"处理第"+counterVal+"本书");
                        if(rating>ratingLine){
                            Document detail = null;
                            try{
                                int beginIndex = detailUrl.substring(0,detailUrl.length()-1).lastIndexOf("/");
                                String id  = detailUrl.substring(beginIndex+1,detailUrl.length()-1);
                                String tag = null;
                                if(url.contains("tag")){
                                    int tagIndex = url.indexOf("tag");
                                    int queIndex = url.indexOf("?");
                                    tag = url.substring(tagIndex+4,queIndex-1).trim();
                                }

                                if(1==getDataType){
                                    resultBook = doubanBookService.findOne(id);
                                }else if(0==getDataType) {
                                    resultBook = getBookDetail(detailUrl,tag);
                                }else if(2==getDataType){
                                    resultBook = doubanBookService.findOne(id);
                                    /*if(!"企业史".equals(resultBook.getTag())){
                                        other++;
                                    }*/
                                    //log.info("other"+other);
                                    //log.info("exist"+exist);

                                    if(null==resultBook){
                                        log.info("库里没有"+id+"---------------------------------------------------------------------------------------------------------------------");
                                        resultBook = getBookDetail(detailUrl,tag);
                                        //Toolkit.getDefaultToolkit().beep();
                                    }else{
                                        //exist++;
                                        //log.info("名称"+resultBook.getBookName());
                                    }
                                }
                            }catch (DuplicateKeyException e){
                                log.error("书籍已经存在，跳过");
                                //exist++;
                                continue;
                            }catch (Exception e2){
                                log.error("获取书籍详情出错",e2.getCause());
                                /*StackTraceElement[] eles =e2.getStackTrace();
                                if(null!=eles && eles.length>0){
                                    log.error(eles[0].getLineNumber()+"行出错");
                                }*/

                                continue;
                            }

                            //System.out.println(name+"------"+url+"------"+isbn);
                            CapitalSearch capitalSearch = new CapitalSearch();
                            if(null==borrowBookService.findOne(resultBook.getIsbn().trim()) ){

                                saveBook("haiDian",resultBook, HaiDianSearch.search(resultBook.getIsbn().trim()));
                                saveBook("chaotu",resultBook,ChaoTuSearch.search(resultBook.getIsbn().trim(),resultBook.getBookName().trim()));
                                saveBook("daXing",resultBook, DaxingSearch.search(resultBook.getIsbn().trim()));
                                saveBook("fangShan",resultBook, FangShanSearch.search(resultBook.getIsbn().trim()));
                                saveBook("haiDian",resultBook, HaiDianSearch.search(resultBook.getIsbn().trim()));
                                saveBook("miYun",resultBook, MiYunSearch.search(resultBook.getIsbn().trim()));
                                saveBook("pingGu",resultBook, PingGuSearch.search(resultBook.getIsbn().trim()));
                                saveBook("shiJingShan",resultBook, ShiJingShanSearch.search(resultBook.getIsbn().trim()));
                                saveBook("tongZhou",resultBook, TongZhouSearch.search(resultBook.getIsbn().trim()));
                                saveBook("yanQing",resultBook, YanQingSearch.search(resultBook.getIsbn().trim()));
                            }

                        }

                    }
                }catch(Exception e){
                    log.error("出错了"+e.getMessage());
                    log.error("StackTrace"+e.getStackTrace());
                    log.error("local",e.getLocalizedMessage());
                    log.error("cause",e.getCause());
                    log.error("press"+e.getSuppressed());
                    log.error("class"+e.getClass());
                }
                //翻页
                bookSum.set(bookSumIncrease(bookSum.get()));
                startIndex+=20;
                log.info("bookSum"+bookSum.get());
                pageNum--;
            }while (pageNum>1);

        }
    }

}
